import {NbGoStep} from '../NbGoStep.js';
import {waitForCondition} from '../GoUtils.js';
import {StrUtil} from '../../../utils/StrUtil.js';

export class FeatureTagBuildStep extends NbGoStep {
    constructor() {
        super({
            key: 'featureTagBuild',
            name: 'Feature-Tag 构建',
            description: '检查发布单构建状态并补齐缺失构建'
        });
    }

    async shouldSkip(context) {
        const {pipeline} = context;
        const {flatten} = await pipeline.getFlowApps(true);
        const pending = flatten.filter(item => item.lastCommitHasBuild !== true);
        context.cache.featureTagPending = pending;
        if (pending.length === 0) {
            return {
                skip: true,
                reason: '所有应用 last_commit_has_build 均为 true',
                metadata: {
                    checkedAt: new Date().toISOString()
                }
            };
        }
        return {skip: false};
    }

    async execute(context) {
        const {logger, opsClient, pipeline} = context;
        const pending = context.cache.featureTagPending || [];
        if (pending.length === 0) {
            return {builtApps: []};
        }
        const buildTargets = pending
            .filter(item => item.flowAppId)
            .map(item => ({
                appName: item.appName,
                flowAppId: item.flowAppId,
                parentApp: item.parentApp
            }));
        if (buildTargets.length === 0) {
            throw new Error('构建列表为空，无法执行');
        }
        logger.info(`需要构建的应用：${buildTargets.map(item => item.appName).join(', ')}`);
        for (const target of buildTargets) {
            logger.info(`触发构建：${target.appName}${target.parentApp ? `(所属 ${target.parentApp})` : ''}`);
            const res = await opsClient.buildAndDeploy(target.flowAppId);
            const status = res?.status;
            if (status && status !== 'success' && res?.message !== '分支正在构建中') {
                throw new Error(`${target.appName} 构建触发失败：${res.message || status}`);
            }
        }
        try {
            await waitForCondition(async () => {
                const {flatten} = await pipeline.getFlowApps(true);
                const latestMap = new Map(flatten.map(item => [item.appName, item]));
                return buildTargets.every(target => {
                    const item = latestMap.get(target.appName);
                    return item?.lastCommitHasBuild === true;
                });
            }, {timeoutMs: this.timeoutMs, intervalMs: 10_000});
        } catch (error) {
            throw new Error(`构建未在限定时间内完成，请手动处理 (${error.message})`);
        }
        return {
            builtApps: buildTargets.map(item => item.appName),
            finishedAt: new Date().toISOString()
        };
    }
}
